package com.qwc.blog.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qwc.blog.common.constant.CommonConstant;
import com.qwc.blog.entity.Classify;
import com.qwc.blog.entity.dto.ClassifyTreeDto;
import com.qwc.blog.mapper.ClassifyMapper;
import com.qwc.blog.service.IClassifyService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章分类表 服务实现类
 * </p>
 *
 * @author qwc
 * @since 2022-01-24
 */
@Service
public class ClassifyServiceImpl extends ServiceImpl<ClassifyMapper, Classify> implements IClassifyService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeClassifyAndChildren(List<Integer> asList) {
        List<Integer> ids = new ArrayList<>();
        ids.addAll(asList);
        getIdsByPid(asList, ids);
        int i = baseMapper.deleteBatchIds(ids);
        return i > 0;
    }

    @Override
    public List<ClassifyTreeDto> getTreeByPid(Integer pid) {
        List<Classify> list = getChildren(pid);
        getAllChildren(list.stream().map(Classify::getClassifyId).collect(Collectors.toList()), list);
        return ClassifyTreeDto.getTree(list, pid, null);
    }

    @Override
    public List<Classify> getChildren(Integer pid) {
        return baseMapper.selectList(Wrappers.<Classify>lambdaQuery()
                .eq(Classify::getPid, pid)
                .eq(Classify::getStatus, CommonConstant.ABLE)
                .orderByAsc(Classify::getSort)
                .orderByDesc(Classify::getCreateTime));
    }

    @Override
    public List<Classify> getClassifyParent(Integer classifyId) {
        List<Classify> list = new ArrayList<>();
        getParent(classifyId,list);
        Collections.reverse(list);
        return list;
    }

    private void getParent(Integer id, List<Classify> classifies) {
        if (!id.equals(CommonConstant.ROOT)) {
            Classify classify = baseMapper.selectOne(Wrappers.<Classify>lambdaQuery().eq(Classify::getClassifyId, id));
            classifies.add(classify);
            getParent(classify.getPid(),classifies);
        }
    }

    private void getAllChildren(List<Integer> pidList, List<Classify> list) {
        for (Integer pid : pidList) {
            List<Classify> children = getChildren(pid);
            if (CollUtil.isNotEmpty(children)) {
                list.addAll(children);
                getAllChildren(children.stream().map(Classify::getClassifyId).collect(Collectors.toList()), list);
            }
        }
    }

    private void getIdsByPid(List<Integer> pid, List<Integer> ids) {
        List<Classify> classifies = baseMapper.selectList(Wrappers.<Classify>lambdaQuery().in(Classify::getPid, pid));
        List<Integer> collect = classifies.stream().map(Classify::getClassifyId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            ids.addAll(collect);
            getIdsByPid(collect, ids);
        }
    }
}
